<template>
  <div class="cascade-select">
    <div @click="showMenu = true">
      <q-field
        :model-value="displayValue"
        readonly
        v-bind="$attrs"
        class="cursor-pointer"
        borderless
        stack-label
      >
        <template v-slot:control>
          <div class="self-center full-width no-outline" tabindex="0">
            {{ displayValue || $attrs.placeholder || '请选择' }}
          </div>
        </template>
        <template v-slot:append>
          <q-icon
            v-if="clearable && displayValue"
            name="close"
            class="cursor-pointer"
            @click.stop="clearSelection"
          />
          <q-icon :name="showMenu ? 'arrow_drop_up' : 'arrow_drop_down'" class="cursor-pointer" />
        </template>
      </q-field>
    </div>

    <q-dialog v-model="showMenu">
      <q-card class="cascade-dialog">
        <q-card-section class="dialog-header row items-center q-px-sm">
          <div class="text-subtitle1">{{ title }}</div>
          <q-space />
          <q-btn flat round icon="close" size="sm" v-close-popup />
        </q-card-section>

        <q-card-section class="dialog-content q-pa-none">
          <div class="column">
            <q-tabs
              v-model="activeTab"
              class="tabs-section justify-start"
              active-color="primary"
              indicator-color="primary"
            >
              <q-tab v-for="(title, index) in tabTitles" :key="index" :name="index">
                <template v-if="selectedPath[index]">
                  {{ getItemLabel(selectedPath[index]) }}
                  <!-- <q-chip dense color="primary" text-color="white" class="q-px-sm">
                    {{ getItemLabel(selectedPath[index]) }}
                  </q-chip> -->
                </template>
                <template v-else>
                  {{ title }}
                </template>
              </q-tab>
            </q-tabs>

            <q-tab-panels v-model="activeTab" animated class="panels-section bg-white">
              <q-tab-panel
                v-for="(level, index) in activePanels"
                :key="index"
                :name="index"
                class="q-pa-none"
              >
                <q-list padding>
                  <q-item
                    v-for="item in level"
                    :key="getItemValue(item)"
                    clickable
                    v-ripple
                    :active="isSelected(item, index)"
                    @click="handleSelect(item, index)"
                    :disable="isItemDisabled(item)"
                    class="cascade-item rounded-borders"
                  >
                    <q-item-section>
                      <q-item-label>{{ getItemLabel(item) }}</q-item-label>
                    </q-item-section>
                    <q-item-section v-if="isSelected(item, index)" side>
                      <q-icon name="check" color="primary" size="xs" />
                    </q-item-section>
                  </q-item>
                  <q-item v-if="level.length === 0" class="text-grey">
                    <q-item-section>暂无数据</q-item-section>
                  </q-item>
                </q-list>
              </q-tab-panel>
            </q-tab-panels>
          </div>
        </q-card-section>
      </q-card>
    </q-dialog>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'

const props = defineProps({
  modelValue: {
    type: [Array, String, Number, Object],
    default: () => [],
  },
  options: {
    type: Array,
    default: () => [],
  },
  valueKey: {
    type: String,
    default: 'value',
  },
  labelKey: {
    type: String,
    default: 'label',
  },
  childrenKey: {
    type: String,
    default: 'children',
  },
  separator: {
    type: String,
    default: ' / ',
  },
  clearable: {
    type: Boolean,
    default: false,
  },
  returnFullPath: {
    type: Boolean,
    default: false,
  },
  disabledKey: {
    type: String,
    default: 'disabled',
  },
  title: {
    type: String,
    default: '请选择',
  },
  panelTitles: {
    type: Array,
    default: () => [],
  },
})

const emit = defineEmits(['update:modelValue', 'change'])

const showMenu = ref(false)
const selectedPath = ref([])
const activePanels = ref([props.options])
const activeTab = ref(0)

// 计算标签页标题
const tabTitles = computed(() => {
  const titles = props.panelTitles.length > 0 ? props.panelTitles : []
  while (titles.length < activePanels.value.length) {
    titles.push(titles.length === 0 ? '请选择' : '')
  }
  return titles
})

// 计算选中路径显示
// const selectedPathDisplay = computed(() => {
//   if (selectedPath.value.length === 0) return ''
//   return selectedPath.value
//     .map((item, index) => `${tabTitles.value[index]}: ${getItemLabel(item)}`)
//     .join(' | ')
// })

const getItemValue = (item) => item?.[props.valueKey]
const getItemLabel = (item) => item?.[props.labelKey]
const hasChildren = (item) =>
  Array.isArray(item?.[props.childrenKey]) && item[props.childrenKey].length > 0
const isItemDisabled = (item) => item?.[props.disabledKey] === true

const displayValue = computed(() => {
  return selectedPath.value.map((item) => getItemLabel(item)).join(props.separator)
})

const isSelected = (item, level) => {
  return getItemValue(selectedPath.value[level]) === getItemValue(item)
}

const handleSelect = (item, level) => {
  if (isItemDisabled(item)) return

  selectedPath.value = selectedPath.value.slice(0, level)
  selectedPath.value.push(item)

  if (hasChildren(item)) {
    activePanels.value = activePanels.value.slice(0, level + 1)
    activePanels.value.push(item[props.childrenKey])
    activeTab.value = level + 1
  } else {
    showMenu.value = false
    emitValue()
  }
}

const emitValue = () => {
  const value = props.returnFullPath
    ? selectedPath.value
    : getItemValue(selectedPath.value[selectedPath.value.length - 1])
  emit('update:modelValue', value)
  emit('change', value, selectedPath.value)
}

const clearSelection = (e) => {
  e.stopPropagation()
  selectedPath.value = []
  activePanels.value = [props.options]
  activeTab.value = 0
  emit('update:modelValue', props.returnFullPath ? [] : null)
  emit('change', props.returnFullPath ? [] : null, [])
}

// 监听选项变化
watch(
  () => props.options,
  (newVal) => {
    activePanels.value = [newVal]
    selectedPath.value = []
    activeTab.value = 0
  },
  { deep: true },
)

// 监听外部值变化
watch(
  () => props.modelValue,
  (newVal) => {
    if (!newVal || (Array.isArray(newVal) && newVal.length === 0)) {
      selectedPath.value = []
      activePanels.value = [props.options]
      activeTab.value = 0
    }
  },
  { deep: true },
)
</script>

<style scoped>
.cascade-select {
  display: inline-block;
  width: 100%;
  cursor: pointer;
}

.cascade-dialog {
  width: 85vw;
  max-width: 600px;
  max-height: 80vh;
  border-radius: 12px;
}

.dialog-header {
  /* height: 44px; */
  border-bottom: 1px solid #eee;
}

.dialog-content {
  height: 500px;
}

.tabs-section {
  width: 100%;
  border-bottom: 1px solid #eee;
}

.panels-section {
  width: 100%;
  height: calc(100% - 48px); /* 减去tabs的高度 */
}

.cascade-item {
  /* min-height: 44px; */
  margin: 4px 8px;
  border-radius: 8px !important;
}

.cascade-item:hover {
  background: #f5f5f5;
}

.cascade-item.q-item--active {
  color: var(--q-primary);
  /* background: #ecf5ff !important; */
}

:deep(.q-tab) {
  justify-content: center;
  padding: 8px 16px;
  border-radius: 0;
  margin: 0;
}

:deep(.q-tab__label) {
  font-size: 14px;
}

:deep(.q-tab--active) {
  font-weight: 500;
  background: #f0f0f0;
}

:deep(.q-chip) {
  height: 24px;
}

/* 自定义滚动条样式 */
.panels-section :deep(.q-panel) {
  overflow-y: auto;
  scrollbar-width: thin;
}

.panels-section :deep(.q-panel::-webkit-scrollbar) {
  width: 4px;
}

.panels-section :deep(.q-panel::-webkit-scrollbar-track) {
  background: #f1f1f1;
}

.panels-section :deep(.q-panel::-webkit-scrollbar-thumb) {
  background: #888;
  border-radius: 4px;
}

.panels-section :deep(.q-panel::-webkit-scrollbar-thumb:hover) {
  background: #555;
}

/* 添加 QField 相关样式 */
:deep(.q-field__control) {
  height: 40px !important;
  padding: 0 12px;
  cursor: pointer;
  min-height: 40px;
}

:deep(.q-field__marginal) {
  height: 40px;
}

:deep(.q-field__native) {
  /* min-height: 40px; */
}
:deep(.q-tabs__content--align-center) {
  justify-content: flex-start;
}
/* 确保实线边框 */
:deep(.q-field--outlined .q-field__control:before) {
  border-style: solid !important;
  border-width: 1px !important;
}

/* 确保悬停和聚焦时也是实线 */
:deep(.q-field--outlined .q-field__control:hover:before) {
  border-style: solid !important;
  border-width: 1px !important;
}

:deep(.q-field--outlined .q-field__control:focus:before) {
  border-style: solid !important;
  border-width: 1px !important;
}

/* 移除底部虚线 */
:deep(.q-field--outlined .q-field__control:after) {
  border: none !important;
}

/* 确保整个控件可点击 */
:deep(.q-field__control-container) {
  cursor: pointer;
}
:deep(.q-field--auto-height .q-field__native) {
  min-height: 0 !important;
}
.q-field--auto-height .q-field__native {
  min-height: 0 !important;
}
</style>
